using System;
using System.ComponentModel.DataAnnotations;
using WalkingTec.Mvvm.Core;

namespace HengTong.Model.Db.Hr.Attendance
{
    /// <summary>
    /// 出勤记录表，根据打卡记录表和排班表计算员工的考勤记录
    /// 替班的打卡是计算到被替班人出勤记录，换班不受影响
    /// </summary>
    public class SysAttendanceReport : TopBasePoco
    {
        /// <summary>
        /// 获取或设置人员ID
        /// </summary>
        /// <value>出勤记录的人员ID</value>
        [Display(Name = "人员", Description = "出勤记录的人员", GroupName = "基本信息")]
        [Required(ErrorMessage = "人员不能为空")]
        public Guid? PersonId { get; set; }

        /// <summary>
        /// 获取或设置人员导航属性
        /// </summary>
        /// <value>出勤记录的人员实体</value>
        public SysPerson Person { get; set; }

        /// <summary>
        /// 获取或设置班次ID
        /// </summary>
        /// <value>关联的班次记录ID</value>
        [Display(Name = "班次", Description = "关联的班次记录", GroupName = "基本信息")]
        [Required(ErrorMessage = "班次不能为空")]
        public Guid? ShiftId { get; set; }

        /// <summary>
        /// 获取或设置班次导航属性
        /// </summary>
        /// <value>关联的班次记录实体</value>
        public SysAttendanceRecord Record { get; set; }

        /// <summary>
        /// 获取或设置考勤日期
        /// </summary>
        /// <value>考勤的具体日期</value>
        [Display(Name = "考勤日期", Description = "考勤的具体日期", GroupName = "时间信息")]
        [Required(ErrorMessage = "考勤日期不能为空")]
        public DateOnly AttendanceDate { get; set; }

        /// <summary>
        /// 获取或设置计划上班时间
        /// </summary>
        /// <value>根据班次规则确定的计划上班时间</value>
        [Display(Name = "计划上班时间", Description = "根据班次规则确定的计划上班时间", GroupName = "时间信息")]
        public DateTime? PlannedStartTime { get; set; }

        /// <summary>
        /// 获取或设置计划下班时间
        /// </summary>
        /// <value>根据班次规则确定的计划下班时间</value>
        [Display(Name = "计划下班时间", Description = "根据班次规则确定的计划下班时间", GroupName = "时间信息")]
        public DateTime? PlannedEndTime { get; set; }

        /// <summary>
        /// 获取或设置实际上班时间
        /// </summary>
        /// <value>实际的上班打卡时间</value>
        [Display(Name = "实际上班时间", Description = "实际的上班打卡时间", GroupName = "时间信息")]
        public DateTime? ActualStartTime { get; set; }

        /// <summary>
        /// 获取或设置实际下班时间
        /// </summary>
        /// <value>实际的下班打卡时间</value>
        [Display(Name = "实际下班时间", Description = "实际的下班打卡时间", GroupName = "时间信息")]
        public DateTime? ActualEndTime { get; set; }

        /// <summary>
        /// 获取或设置迟到分钟数
        /// </summary>
        /// <value>迟到的分钟数，0表示未迟到</value>
        [Display(Name = "迟到(分钟)", Description = "迟到的分钟数", GroupName = "考勤结果")]
        public int LateMinutes { get; set; } = 0;

        /// <summary>
        /// 获取或设置早退分钟数
        /// </summary>
        /// <value>早退的分钟数，0表示未早退</value>
        [Display(Name = "早退(分钟)", Description = "早退的分钟数", GroupName = "考勤结果")]
        public int EarlyMinutes { get; set; } = 0;

        /// <summary>
        /// 获取或设置工作时长
        /// </summary>
        /// <value>实际工作时长，以分钟计</value>
        [Display(Name = "工作时长(分钟)", Description = "实际工作时长，以分钟计", GroupName = "考勤结果")]
        public int WorkMinutes { get; set; } = 0;

        /// <summary>
        /// 获取或设置出勤状态
        /// </summary>
        /// <value>出勤状态：正常、迟到、早退、旷工、请假、调休等</value>
        [Display(Name = "出勤状态", Description = "出勤状态：正常、迟到、早退、旷工、请假、调休等", GroupName = "考勤结果")]
        [Required(ErrorMessage = "出勤状态不能为空")]
        [MaxLength(32)]
        public string AttendanceStatus { get; set; }

        /// <summary>
        /// 获取或设置是否异常
        /// </summary>
        /// <value>是否存在考勤异常</value>
        [Display(Name = "是否异常", Description = "是否存在考勤异常", GroupName = "考勤结果")]
        public bool IsAbnormal { get; set; } = false;

        /// <summary>
        /// 获取或设置异常原因
        /// </summary>
        /// <value>考勤异常的具体原因</value>
        [Display(Name = "异常原因", Description = "考勤异常的具体原因", GroupName = "考勤结果")]
        [MaxLength(256)]
        public string AbnormalReason { get; set; }

        /// <summary>
        /// 获取或设置应记天数
        /// </summary>
        /// <value>该出勤记录应记的考勤天数</value>
        [Display(Name = "应记天数", Description = "该出勤记录应记的考勤天数", GroupName = "考勤结果")]
        public decimal AttendanceDays { get; set; } = 0m;

        /// <summary>
        /// 获取或设置实际替班人员ID
        /// </summary>
        /// <value>实际替班的人员ID，用于替班情况</value>
        [Display(Name = "实际替班人员", Description = "实际替班的人员", GroupName = "替班信息")]
        public Guid? ActualSubstitutePersonId { get; set; }

        /// <summary>
        /// 获取或设置实际替班人员导航属性
        /// </summary>
        /// <value>实际替班的人员实体</value>
        public SysPerson ActualSubstitutePerson { get; set; }

        /// <summary>
        /// 获取或设置计算时间
        /// </summary>
        /// <value>出勤记录被计算生成的时间</value>
        [Display(Name = "计算时间", Description = "出勤记录被计算生成的时间", GroupName = "技术信息")]
        public DateTime? CalculatedTime { get; set; }

        /// <summary>
        /// 获取或设置备注
        /// </summary>
        /// <value>出勤记录的备注信息</value>
        [Display(Name = "备注", Description = "出勤记录的备注信息", GroupName = "基本信息")]
        [MaxLength(512)]
        public string Remark { get; set; }
    }
}
